import * as React from 'react';
import ReactMarkdown from 'react-markdown';
import gfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import remarkToc from 'remark-toc';
import emoji from 'remark-emoji';
import hint from 'remark-hint';
// import collapse from 'remark-collapse';
// import 'katex/dist/katex.min.css';
import CodeBox from '../code-block/CodeBox';
import { Table, Image } from 'antd';
// import fallbackSrc from './assets/hold.jpg';
import './styles/index.global.less';

export interface MdBlockProps {
  content: string;
}

interface OB {
  type: string;
  tagName: string;
  properties: Record<string, any>;
  children: OB[];
  value: string;
}

const loop = (widget: OB) => {
  const { children } = widget;
  const headRows: string[] = [];
  const rows: string[][] = [];
  children.map((item) => {
    if (item.type === 'element') {
      if (item.tagName === 'thead') {
        item.children.forEach((tr) => {
          if (tr.type === 'element' && tr.tagName === 'tr') {
            tr.children.forEach((td) => {
              if (td.type === 'element' && td.tagName === 'th') {
                td.children.forEach((tt) => {
                  headRows.push(tt.value);
                });
              }
            });
          }
        });
      } else if (item.tagName === 'tbody') {
        item.children.forEach((tr) => {
          if (tr.type === 'element' && tr.tagName === 'tr') {
            const row: string[] = [];
            tr.children.forEach((td) => {
              if (td.type === 'element' && td.tagName === 'td') {
                let str = '';
                td.children.forEach((tt) => {
                  if (tt.type === 'element') {
                    if (tt.tagName === 'code') {
                      tt.children.forEach((ttc) => {
                        if (ttc.type === 'text') {
                          str += `<code>${ttc.value}</code>`;
                        }
                      });
                    }
                  } else if (tt.type === 'text') {
                    str += tt.value;
                  }
                });
                row.push(str);
              }
            });
            rows.push(row);
          }
        });
      }
    }
  });
  return {
    columns: headRows.map((item, i) => {
      return {
        title: item,
        dataIndex: 'col_' + String(i),
        render: (text: string) => {
          return <span dangerouslySetInnerHTML={{ __html: text }} />;
        },
      };
    }),
    dataSource: rows.map((row) =>
      row.reduce<Record<string, any>>((acc, c, col) => {
        acc['col_' + col] = c;
        return acc;
      }, {})
    ),
  };
};

const loopText = (widget: OB) => {
  let str = '';
  widget.children.forEach((tt) => {
    if (tt.type === 'element') {
      if (tt.tagName === 'code') {
        tt.children.forEach((ttc) => {
          if (ttc.type === 'text') {
            str += `<code>${ttc.value}</code>`;
          }
        });
      }
    } else if (tt.type === 'text') {
      str += tt.value;
    }
  });
  return str;
};

class MdBlock extends React.Component<MdBlockProps, any> {
  static propTypes = {};
  static defaultProps = {
    content: '',
  };

  render() {
    const { content } = this.props;
    return (
      <div>
        <ReactMarkdown
          className="markdown-body"
          // allowDangerousHtml
          allowElement={(node, index, parent) => {
            if (node.tagName === 'html') {
              // filter style
              // node.children[] = (node.value as string).replace(
              //   /<((style|script|link|input|form)|\/(style|script|link|input|form))(\s?[^>]*>)/gi,
              //   (a: string) => {
              //     return a.replace(
              //       /[<>]/g,
              //       (e: string) =>
              //         ((
              //           {
              //             '<': '&lt;',
              //             '>': '&gt;',
              //           } as { [key: string]: string }
              //         )[e])
              //     );
              //   }
              // );
            }
            return true;
          }}
          rehypePlugins={[rehypeKatex]}
          remarkPlugins={[[gfm, { singleTilde: false }], remarkToc, emoji as any, hint, remarkMath]}
          components={{
            code: ({ node, inline, className, children, ...props }) => {
              const match = /language-(\w+)/.exec(className || '');
              return !inline && match ? (
                <CodeBox language={match[1]} source={String(children).replace(/\n$/, '')} />
              ) : (
                <code className={className} {...props}>
                  {children}
                </code>
              );
            },
            table: (obj) => {
              // console.log(obj);
              const { node, className, children, ...props } = obj;
              const { columns, dataSource } = loop(node as any);
              // console.log(columns, dataSource);
              return (
                <Table
                  className="v-render-table"
                  bordered
                  size="small"
                  pagination={false}
                  columns={columns}
                  dataSource={dataSource}
                />
              );
            },
            img: (obj) => {
              const { node, className, children, ...props } = obj;
              const src = obj.node.properties!.src as string;
              const alt = obj.node.properties!.alt as string;
              return (
                <div className="v-image-container">
                  <Image
                    width="100%"
                    placeholder={
                      <div className="v-image-loading">
                        <img src="http://placeholder.idcd.com/?w=400&h=122&text=Image+loading....&bgcolor=%233995E7&fontcolor=%23FFFFFF&fontsize=0&fontfamily=3" />
                      </div>
                    }
                    src={src}
                    alt={alt}
                    preview={false}
                    // fallback={fallbackSrc}
                    fallback="http://placeholder.idcd.com/?w=740&h=122&text=Image+load+faild%21&bgcolor=%233995E7&fontcolor=%23FFFFFF&fontsize=0&fontfamily=3"
                  />
                </div>
              );
            },
            a: (obj) => {
              return (
                <a
                  href={obj.node.properties?.href as string}
                  target="_blank"
                  referrerPolicy="no-referrer"
                  rel="noreferrer"
                >
                  {loopText(obj.node as any)}
                </a>
              );
            },
          }}
        >
          {content}
        </ReactMarkdown>
      </div>
    );
  }
}

export default MdBlock;
